package start.demo01.erupt;

import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/**
 * 阻塞队列：当尝试向满队列添加一个元素或者从空队列中删除一个元素会导致线程阻塞
 * ArrayBlockingQueue
 * 		底层采用数组实现阻塞队列，必须为队列指定容量或者可选的公平策略来创建
 * LinkedBlockingQueue
 * 		底层采用链表实现阻塞队列，可以创建无边界的或者有边界的LinkedBlockingQueue
 * PriorityBlockingQueue 优先队列
 * @author Adan
 *
 */
public class ProducerConsumerUsingBlockingQueue {
	public static final int CAPACITY = 20;
	private static ArrayBlockingQueue<Task> buffer = new ArrayBlockingQueue<Task>(CAPACITY);
	public static void main(String[] args) {
		ExecutorService pool = Executors.newFixedThreadPool(2);
		pool.execute(new ProducerTask());
		pool.execute(new ConsumerTask());
		pool.shutdown();
	}
	
	private static class ProducerTask implements Runnable{
		@Override
		public void run() {
			try {
				while(true) {
					Thread.sleep((int)(Math.random() * 1000));
					Task task = new Task();
					buffer.put(task);
					System.out.println("Producer[" + Thread.currentThread().getName() + "] put " + task);
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	private static class ConsumerTask implements Runnable{
		@Override
		public void run() {
			try {
				while(true) {
					Thread.sleep((int)(Math.random() * 1000));
					System.out.println("Cousumer[" + Thread.currentThread().getName() + "] got " + buffer.remove());
					//被各种访问器方法抛出，表示被请求的元素不存在。
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	private static class Task{
		private String id;
		public Task() {
			this.id = UUID.randomUUID().toString();
		}
		@Override
		public String toString() {
			return "Task [id=" + id + "]";
		}
	}
	
}
